home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / pack < prev    next >
Encoding:
Text File  |  1988-04-08  |  8.0 KB  |  412 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *        pack.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "heap.h"
  14. #include "arith.h"
  15. #include "scan.h"
  16. #include "tokenstack.h"
  17. #include "eq.h"
  18. #include "eqstack.h"
  19. #include "evalstack.h"
  20. #include "box.h"
  21. #include "tfm.h"
  22. #include "dvi.h"
  23. #include "print.h"
  24. #include "error.h"
  25. #include "pack.h"
  26.  
  27. ptr        adjust_tail;
  28. val        pack_begin_line;
  29. scal    total_shrink[4];
  30. scal    total_stretch[4];
  31.  
  32. #define    clr_dimens() \
  33.     {d = x = 0; \
  34.     total_stretch[FILLL] = 0; \
  35.     total_stretch[FILL] = 0; \
  36.     total_stretch[FIL] = 0; \
  37.     total_stretch[NORMAL] = 0; \
  38.     total_shrink[FILLL] = 0; \
  39.     total_shrink[FILL] = 0; \
  40.     total_shrink[FIL] = 0; \
  41.     total_shrink[NORMAL] = 0;}
  42.  
  43. ptr
  44. hpack (p, w, m)
  45.     ptr        p;
  46.     scal    w;
  47.     int        m;
  48. {
  49.     int        b;
  50.     scal    d;
  51.     fnt        f;
  52.     ptr        g;
  53.     scal    h;
  54.     fourq    i;
  55.     gord    o;
  56.     ptr        q;
  57.     ptr        r;
  58.     scal    s;
  59.     scal    x;
  60.     byte    hd;
  61.  
  62.     r = get_node(BOX_NODE_SIZE);
  63.     type(r) = HLIST_NODE;
  64.     subtype(r) = MIN_QUARTERWORD;
  65.     shift_amount(r) = 0;
  66.     q = r + LIST_OFFSET;
  67.     link(q) = p;
  68.     h = 0;
  69.     clr_dimens();
  70.     while (p != NULL) {
  71. reswitch:
  72.         while (is_char_node(p)) {
  73.             f = font(p);
  74.             i = char_info(f, character(p));
  75.             hd = height_depth(i);
  76.             x += char_width(f, i);
  77.             s = char_height(f, hd);
  78.             if (s > h)
  79.                 h = s;
  80.             s = char_depth(f, hd);
  81.             if (s > d)
  82.                 d = s;
  83.             p = link(p);
  84.         }
  85.         if (p != NULL) {
  86.             switch (type(p))
  87.             {
  88.             case HLIST_NODE:
  89.             case VLIST_NODE:
  90.             case RULE_NODE:
  91.             case UNSET_NODE:
  92.                 x += width(p);
  93.                 if (type(p) >= RULE_NODE)
  94.                     s = 0;
  95.                 else s = shift_amount(p);
  96.                 if (height(p) - s > h)
  97.                     h = height(p) - s;
  98.                 if (depth(p) + s > d)
  99.                     d = depth(p) + s;
  100.                 break;
  101.  
  102.             case INS_NODE:
  103.             case MARK_NODE:
  104.             case ADJUST_NODE:
  105.                 if (adjust_tail != NULL) {
  106.                     while (link(q) != p)
  107.                         q = link(q);
  108.                     if (type(p) == ADJUST_NODE) {
  109.                         link(adjust_tail) = adjust_ptr(p);
  110.                         while (link(adjust_tail) != NULL)
  111.                             adjust_tail = link(adjust_tail);
  112.                         p = link(p);
  113.                         free_node(link(q), SMALL_NODE_SIZE);
  114.                     } else {
  115.                         link(adjust_tail) = p;
  116.                         adjust_tail = p;
  117.                         p = link(p);
  118.                     }
  119.                     link(q) = p;
  120.                     p = q;
  121.                 }
  122.                 break;
  123.  
  124.             case WHATSIT_NODE:
  125.                 break;
  126.             
  127.             case GLUE_NODE:
  128.                 g = glue_ptr(p);
  129.                 x += width(g);
  130.                 o = stretch_order(g);
  131.                 total_stretch[o] += stretch(g);
  132.                 o = shrink_order(g);
  133.                 total_shrink[o] += shrink(g);
  134.                 if (subtype(p) >= A_LEADERS) {
  135.                     g = leader_ptr(p);
  136.                     if (height(g) > h)
  137.                         h = height(g);
  138.                     if (depth(g) > d)
  139.                         d = depth(g);
  140.                 }
  141.                 break;
  142.             
  143.             case KERN_NODE:
  144.             case MATH_NODE:
  145.                 x += width(p);
  146.                 break;
  147.             
  148.             case LIGATURE_NODE:
  149.                 make_char_from_lig();
  150.                 goto reswitch;
  151.                 break;
  152.  
  153.             default:
  154.                 break;
  155.             }
  156.             p = link(p);
  157.         }
  158.     }
  159.     if (adjust_tail != NULL)
  160.         link(adjust_tail) = NULL;
  161.     height(r) = h;
  162.     depth(r) = d;
  163.     if (m == ADDITIONAL)
  164.         w += x;
  165.     width(r) = w;
  166.     x = w - x;
  167.     if (x == 0) {
  168.         glue_sign(r) = NORMAL;
  169.         glue_order(r) = NORMAL;
  170.         glue_set(r) = 0.0;
  171.         return r;
  172.     } else if (x > 0) {
  173.         get_stretch_order(); 
  174.         glue_order(r) = o;
  175.         glue_sign(r) = STRETCHING;
  176.         if (total_stretch[o] != 0)
  177.             glue_set(r) = (float) x / total_stretch[o];
  178.         else {
  179.             glue_sign(r) = NORMAL;
  180.             glue_set(r) = 0.0;
  181.         }
  182.         if (hbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
  183.             b = badness(x, total_stretch[NORMAL]);
  184.             if (b > hbadness) {
  185.                 print_ln();
  186.                 if (b > 100)
  187.                     print_nl("Underfull");
  188.                 else print_nl("Loose");
  189.                 print(" \\hbox (badness ");
  190.                 print_int(b);
  191.                 goto common_end;
  192.             }
  193.         }
  194.         return r;
  195.     } else {
  196.         get_shrink_order();
  197.         glue_order(r) = o;
  198.         glue_sign(r) = SHRINKING;
  199.         if (total_shrink[o] != 0)
  200.             glue_set(r) = (float) -x / total_shrink[o];
  201.         else {
  202.             glue_sign(r) = NORMAL;
  203.             glue_set(r) = 0.0;
  204.         }
  205.         if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
  206.             glue_set(r) = 1.0;
  207.             if (-x - total_shrink[NORMAL] > hfuzz || hbadness < 100) {
  208.                 if (overfull_rule > 0 && -x - total_shrink[NORMAL] > hfuzz) {
  209.                     while (link(q) != NULL)
  210.                         q = link(q);
  211.                     link(q) = new_rule();
  212.                     width(link(q)) = overfull_rule;
  213.                 }
  214.                 print_ln();
  215.                 print_nl("Overfull \\hbox ("); 
  216.                 print_scaled(-x - total_shrink[NORMAL]);
  217.                 print("pt too wide");
  218.                 goto common_end;
  219.             }
  220.         } else if (hbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
  221.             b = badness(-x, total_shrink[NORMAL]);
  222.             if (b > hbadness) {
  223.                 print_ln();
  224.                 print_nl("Tight \\hbox (badness ");
  225.                 print_int(b);
  226.                 goto common_end;
  227.             }
  228.         }
  229.         return r;
  230.     }
  231.  
  232. common_end:
  233.     if (output_active)
  234.         print(") has occurred while \\output is active");
  235.     else {
  236.         if (pack_begin_line != 0) {
  237.             if (pack_begin_line > 0)
  238.                 print(") in paragraph at lines ");
  239.             else print(") in alignment at lines ");
  240.             print_val(abs(pack_begin_line));
  241.             print("--");
  242.         } else print(") detected at line ");
  243.         print_val(line);
  244.     }
  245.     print_ln();
  246.     font_in_short_display = NULL_FONT;
  247.     short_display(list_ptr(r));
  248.     print_ln();
  249.     begin_diagnostic();
  250.     show_box(r);
  251.     end_diagnostic(TRUE);
  252.     return r;
  253. }
  254.  
  255. ptr
  256. vpackage (p, h, m, l)
  257.     ptr        p;
  258.     scal    h;
  259.     int        m;
  260.     scal    l;
  261. {
  262.     int        b;
  263.     scal    d;
  264.     ptr        g;
  265.     gord    o;
  266.     ptr        r;
  267.     scal    s;
  268.     scal    w;
  269.     scal    x;
  270.  
  271.     r = get_node(BOX_NODE_SIZE);
  272.     type(r) = VLIST_NODE;
  273.     subtype(r) = MIN_QUARTERWORD;
  274.     shift_amount(r) = 0;
  275.     list_ptr(r) = p;
  276.     w = 0;
  277.     clr_dimens();
  278.     while (p != NULL) {
  279.         if (is_char_node(p))
  280.             confusion("vpack");
  281.         else {
  282.             switch (type(p))
  283.             {
  284.             case HLIST_NODE:
  285.             case VLIST_NODE:
  286.             case RULE_NODE:
  287.             case UNSET_NODE:
  288.                 x += d + height(p);
  289.                 d = depth(p);
  290.                 if (type(p) >= RULE_NODE)
  291.                     s = 0;
  292.                 else s = shift_amount(p);
  293.                 if (width(p) + s > w)
  294.                     w = width(p) + s;
  295.                 break;
  296.             
  297.             case WHATSIT_NODE:
  298.                 break;
  299.             
  300.             case GLUE_NODE:
  301.                 x += d;
  302.                 d = 0;
  303.                 g = glue_ptr(p);
  304.                 x += width(g);
  305.                 o = stretch_order(g);
  306.                 total_stretch[o] += stretch(g);
  307.                 o = shrink_order(g);
  308.                 total_shrink[o] += shrink(g);
  309.                 if (subtype(p) >= A_LEADERS) {
  310.                     g = leader_ptr(p);
  311.                     if (width(g) > w)
  312.                         w = width(g);
  313.                 }
  314.                 break;
  315.             
  316.             case KERN_NODE:
  317.                 x += d + width(p);
  318.                 d = 0;
  319.                 break;
  320.  
  321.             default:
  322.                 break;
  323.             }
  324.             p = link(p);
  325.         }
  326.     }
  327.     width(r) = w;
  328.     if (d > l) {
  329.         x += d - l;
  330.         depth(r) = l;
  331.     } else depth(r) = d;
  332.     if (m == ADDITIONAL)
  333.         h += x;
  334.     height(r) = h;
  335.     x = h - x;
  336.     if (x == 0) {
  337.         glue_sign(r) = NORMAL;
  338.         glue_order(r) = NORMAL;
  339.         glue_set(r) = 0.0;
  340.         return r;
  341.     } else if (x > 0) {
  342.         get_stretch_order();
  343.         glue_order(r) = o;
  344.         glue_sign(r) = STRETCHING;
  345.         if (total_stretch[o] != 0)
  346.             glue_set(r) = (float) x / total_stretch[o];
  347.         else {
  348.             glue_sign(r) = NORMAL;
  349.             glue_set(r) = 0.0;
  350.         }
  351.         if (vbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
  352.             b = badness(x, total_stretch[NORMAL]);
  353.             if (b > vbadness) {
  354.                 print_ln();
  355.                 if (b > 100)
  356.                     print_nl("Underfull");
  357.                 else print_nl("Loose");
  358.                 print(" \\vbox (badness ");
  359.                 print_int(b);
  360.                 goto common_end;
  361.             }
  362.         }
  363.         return r;
  364.     } else {
  365.         get_shrink_order();
  366.         glue_order(r) = o;
  367.         glue_sign(r) = SHRINKING;
  368.         if (total_shrink[o] != 0)
  369.             glue_set(r) = (float) -x / total_shrink[o];
  370.         else {
  371.             glue_sign(r) = NORMAL;
  372.             glue_set(r) = 0.0;
  373.         }
  374.         if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
  375.             glue_set(r) = 1.0;
  376.             if (-x - total_shrink[NORMAL] > vfuzz || vbadness < 100) {
  377.                 print_ln();
  378.                 print_nl("Overfull \\vbox (");
  379.                 print_scaled(-x - total_shrink[NORMAL]);
  380.                 print("pt too high");
  381.                 goto common_end;
  382.             }
  383.         } else if (vbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
  384.             b = badness(-x, total_shrink[NORMAL]);
  385.             if (b > vbadness) {
  386.                 print_ln();
  387.                 print_nl("Tight \\vbox (badness ");
  388.                 print_int(b);
  389.                 goto common_end;
  390.             }
  391.         }
  392.         return r;
  393.     }
  394.  
  395. common_end:
  396.     if (output_active)
  397.         print(") has occurred while \\output is active");
  398.     else {
  399.         if (pack_begin_line != 0) {
  400.             print(") in alignment at lines ");
  401.             print_val(abs(pack_begin_line));
  402.             print("--");
  403.         } else print(") detected at line ");
  404.         print_val(line);
  405.         print_ln();
  406.     }
  407.     begin_diagnostic();
  408.     show_box(r);
  409.     end_diagnostic(TRUE);
  410.     return r;
  411. }
  412.